home *** CD-ROM | disk | FTP | other *** search
/ PC World Komputer 2007 December / PCWKCD1207B.iso / Blogowanie poza sfera / Flock 1.0 beta / flock-1.0RC3.en-US.win32.exe / flock / components / flockBlogWebServiceAtom.js < prev    next >
Text File  |  2007-10-18  |  15KB  |  447 lines

  1. // BEGIN FLOCK GPL
  2. // 
  3. // Copyright Flock Inc. 2005-2007
  4. // http://flock.com
  5. // 
  6. // This file may be used under the terms of of the
  7. // GNU General Public License Version 2 or later (the "GPL"),
  8. // http://www.gnu.org/licenses/gpl.html
  9. // 
  10. // Software distributed under the License is distributed on an "AS IS" basis,
  11. // WITHOUT WARRANTY OF ANY KIND, either express or implied. See the License
  12. // for the specific language governing rights and limitations under the
  13. // License.
  14. // 
  15. // END FLOCK GPL
  16.  
  17. const Cc = Components.classes;
  18. const Ci = Components.interfaces;
  19.  
  20. const nsISupports           = Ci.nsISupports;
  21. const nsIXMLHttpRequest       = Ci.nsIXMLHttpRequest;
  22.  
  23. const XMLHTTPREQUEST_CONTRACTID   = '@mozilla.org/xmlextras/xmlhttprequest;1';
  24. const FLOCK_ATOM_CID        = Components.ID('{0c01e44c-a61e-4e44-8dee-151d99c54dcf}');
  25. const FLOCK_ATOM_CONTRACTID     = '@flock.com/blog/service/atom;1';
  26. const FLOCK_ATOM_DESCRIPTION    = 'ATOM Blog API';
  27.  
  28. const FLOCK_BLOG_RDF_SETTINGS     = 'urn:flock:blog:settings';
  29.  
  30. function loadLibraryFromSpec(aSpec) {
  31.   var loader = Cc['@mozilla.org/moz/jssubscript-loader;1']
  32.     .getService(Ci.mozIJSSubScriptLoader);
  33.  
  34.   loader.loadSubScript(aSpec);
  35. }
  36.  
  37. loadLibraryFromSpec("chrome://flock/content/blog/atom.js");
  38. loadLibraryFromSpec("chrome://flock/content/blog/technoratiTags.js");
  39. loadLibraryFromSpec("chrome://flock/content/blog/blogBackendLib.js");
  40.  
  41. // nsISimpleEnumerator implementation
  42. function simpleEnumerator (aArray) {
  43.   aArray.hasMoreElements = function () { 
  44.     return this.length != 0; 
  45.   }
  46.   aArray.getNext = function () { 
  47.     return this.shift (); 
  48.   }
  49.   return aArray;
  50. }
  51.  
  52. // CONSTRUCTOR 
  53. function atomWebService () {
  54.   this.mQueue = null;
  55.  
  56.   // set attributes
  57.   this.configurationDialog = null;
  58.   this.name = 'ATOM';
  59.   this.shortName = 'atom';
  60.   this.description = "The Atom Publishing Protocol"
  61.   this.supportsCategories = 0;
  62.   this.supportsPostReplace = true;
  63.  
  64.   // Logger
  65.   // this.logger = Cc['@flock.com/logger;1'].createInstance(Ci.flockILogger); 
  66.   // this.logger.init("blog");
  67.   // The logger is buggy?
  68.   this.logger = {};
  69.   this.logger.info = function(txt) { debug("Atom:info:"+txt+"\n"); };
  70.   this.logger.error = function(txt) { debug("Atom:error:"+txt+"\n"); };
  71. }// END CONSTRUCTOR
  72.  
  73. // the nsISupports implementation
  74. atomWebService.prototype.QueryInterface = function (iid) {
  75.   if (iid.equals(Ci.flockICustomBlogWebService) ||
  76.       iid.equals(Ci.flockIBlogWebService) || 
  77.       iid.equals(Ci.nsIClassInfo) || 
  78.       iid.equals(Ci.nsISupports)) {
  79.     return this;
  80.   }
  81.  
  82.   throw Components.results.NS_ERROR_NO_INTERFACE;
  83. }
  84.  
  85. // PRIVATE METHODS  
  86.  
  87. atomWebService.prototype.doRequest = function(listener, method, url, body, processor, aUsername, aPassword) {
  88.   var inst = this;
  89.   this._req = Cc[XMLHTTPREQUEST_CONTRACTID].createInstance(nsIXMLHttpRequest);
  90.   this._req.onreadystatechange = function (aEvt) {
  91.     inst.logger.info("<<<<<<<<<< Atom API: SERVER TO FLOCK\n");
  92.     inst.logger.info("Request readyState: "+inst._req.readyState+"\n");
  93.     if(inst._req.readyState == 4) {
  94.       inst.logger.info("Request status: "+inst._req.status+"\n");    
  95.       inst.logger.info("\nRESPONSE\n" + inst._req.responseText);
  96.       try {
  97.         if(inst._req.status == 200 || inst._req.status == 201 || inst._req.status == 205) {
  98.         try {
  99.             processor(listener, inst);
  100.           }
  101.           catch(e) {
  102.             // listener.onError(inst.ERROR_PARSER);
  103.             inst.logger.error(e + " " + e.lineNumber+"\n");
  104.           }
  105.         }
  106.         else {
  107.           var faultString; //: "Make sure that are not trying to blog really weird html, and note the following kind user:\n\n",
  108.           // };
  109.           faultString = inst._req.responseText;
  110.           //faultString += inst._req;
  111.         inst.logger.error(faultString+"\n");
  112.         listener.onFault(faultString);
  113.         }
  114.       } catch(e) {
  115.         inst.logger.error(e + " " + e.fileName + " " + e.lineNumber + "\n");
  116.         listener.onError(inst.ERROR_PARSER);
  117.       }
  118.     }
  119.   };
  120.   rval = this._req.open(method, url, true, aUsername, aPassword);
  121.   this.logger.info(">>>>>>>>>> Atom API: FLOCK TO SERVER");
  122.   this.logger.info("\nSENDING\n" + body);
  123.   this.logger.info("\nTO\n" + method + " @ " + url);
  124.   rval = this._req.send(body); 
  125. }
  126.  
  127.  
  128. atomWebService.prototype.parseUsersBlogs = function(listener, inst) {
  129.     debug("atomWebService.prototype.parseUsersBlogs\n");
  130.     var result = new Array();
  131.     var dom = inst._req.responseXML;
  132.     var domEntries = dom.getElementsByTagName("entry");
  133.  
  134.     if (domEntries.length > 0) { // Regular ATOM feed (ATOM)
  135.       for (i=0; i<domEntries.length; i++) {
  136.         debug("One entry...\n");
  137.         domEntry = domEntries[i];
  138.         title = domEntry.getElementsByTagName("title")[0].textContent;
  139.         var newAccount = new BlogAccount(title);
  140.         newAccount.api = this.shortName;
  141.         var links = domEntry.getElementsByTagName("link");
  142.         for (j=0; j<links.length; j++) {
  143.           var link = links[j]
  144.           switch (link.getAttribute("rel")) {
  145.             case "alternate":
  146.               newAccount.URL = link.getAttribute("href");
  147.               break;
  148.             case "http://schemas.google.com/g/2005#post":
  149.               newAccount.apiLink = link.getAttribute("href");
  150.               break;
  151.           }
  152.         }
  153.         result.push(newAccount);
  154.       }
  155.     }
  156.     else { // Just a list of links (Livejournal)
  157.       var links = dom.getElementsByTagName("link");
  158.       var result = new Array();
  159.       for(var i=0;i<links.length;++i) {
  160.         var link = links[i];
  161.         var title = link.getAttribute("title");
  162.         var rel = link.getAttribute("rel");
  163.         var href = link.getAttribute("href");
  164.         switch (rel) {
  165.         case "service.post":
  166.           href.match(/.+\/(.+)/);
  167.           var newAccount = new BlogAccount(title);
  168.           newAccount.api = this.shortName;
  169.           newAccount.blogid = RegExp.$1;
  170.           newAccount.apiLink = href;
  171.           newAccount.editLink = href;
  172.           result.push(newAccount);
  173.           break;
  174.         case "alternate":
  175.           for (j in result)
  176.           if (result[j].title == title)
  177.             result[j].URL = href;
  178.           break;
  179.         default: ;
  180.         }
  181.       }
  182.     }
  183.     debug("Found "+ result.length +" blogs\n");
  184.     listener.onResult(simpleEnumerator(result));
  185. }
  186.  
  187.  
  188. atomWebService.prototype.parseRecentPosts = function(listener, inst) {
  189.   var dom = inst._req.responseXML;
  190.   var entries = dom.getElementsByTagName("entry");
  191.  
  192.   var result = new Array();
  193.   for(var i=0;i<entries.length;++i) {
  194.     try {
  195.       var entry_n = entries[i];
  196.       var title_n = inst.getNamedChild(entry_n, "title");
  197.       var created_n = inst.getNamedChild(entry_n, "published");
  198.       var link_n = null;
  199.       var permalink_n = null;
  200.       var atomid_n = inst.getNamedChild(entry_n, "id");
  201.       var atomid = "";
  202.       if(atomid_n) atomid = atomid_n.firstChild.nodeValue;
  203.  
  204.       for(var j=0;j<entry_n.childNodes.length;++j) {
  205.         if(entry_n.childNodes[j].nodeName=="link") {
  206.           var tmp = entry_n.childNodes[j];
  207.           if(tmp.getAttribute("rel").match(/edit/)) {
  208.             link_n = tmp;
  209.           }
  210.           if(tmp.getAttribute("rel").match(/alternate/)) {
  211.             permalink_n = tmp;
  212.           }
  213.         }
  214.       }
  215.  
  216.       var permaLink = permalink_n.getAttribute("href");
  217.       var href = link_n.getAttribute("href");
  218.       href.match(/.+\/(.+)/);
  219.       var postid = RegExp.$1;
  220.  
  221.       var date = created_n.firstChild.nodeValue;
  222.  
  223.       var post = new BlogPost();
  224.       post.title = title_n.firstChild.nodeValue;
  225.       post.issued = date;
  226.       post.postid = atomid;
  227.       result.push(post);
  228.     }
  229.     catch(e) {
  230.       var logger = Cc['@flock.com/logger;1']
  231.         .createInstance(Ci.flockILogger);
  232.       logger.error(e + " " + e.lineNumber + " " + e.fileName);
  233.     }
  234.   }
  235.   listener.onResult(simpleEnumerator(result));
  236. }
  237.  
  238. atomWebService.prototype.getNamedChild = function(node, name) {
  239.   for(var i=0;i<node.childNodes.length;++i) {
  240.     if(node.childNodes[i].nodeName==name)
  241.       return node.childNodes[i];
  242.   }
  243.   return null;
  244. }
  245.  
  246. atomWebService.prototype.handleDelete = function(listener, inst) {
  247.   listener.onResult(1);
  248. }
  249.  
  250. function atomListener(aListener){
  251.   this.listener = aListener;
  252.   this.logger = Cc['@flock.com/logger;1']
  253.     .createInstance(Ci.flockILogger);
  254.   this.logger.init("blog");
  255. }
  256.  
  257. atomListener.prototype = {
  258.   onResult: function(aResult) {
  259.     debug("atomListener, onResult\n");
  260.     var link = aResult.link ? aResult.link : "";
  261.     this.listener.onResult(link);
  262.   },
  263.   onError: function(error) {
  264.     this.logger.error("<<<<<<<<<< Atom API: SERVER TO FLOCK\n");
  265.     this.logger.error("ERROR "+error+"\n");
  266.     this.listener.onError(error);
  267.   }, 
  268.   onFault: function(error) {
  269.     this.logger.error("<<<<<<<<<< Atom API: SERVER TO FLOCK\n");
  270.     this.logger.error("FAULT "+error+"\n");
  271.     this.listener.onFault(error);
  272.   } 
  273. }
  274.  
  275. // END PRIVATE METHODS 
  276.  
  277.  
  278. // the flockIBlogWebService implementation 
  279.  
  280. atomWebService.prototype.detectAccount = function (aUrl, aLinkList){
  281.   while(aLinkList.hasMoreElements()) {
  282.     var link = aLinkList.getNext();
  283.     link.QueryInterface(Ci['flockIBlogLink']);
  284.     debug("   ATOM link.href : "+link.href+"\n");
  285.     if(link.type=="application/atom+xml" && link.rel=="service.post") {
  286.       var account = {
  287.         api : "atom",
  288.         apiLink : link.href
  289.       };
  290.       if (account.apiLink.match(/livejournal/)) {
  291.         debug("Forcing default Livejournal API link.\n");
  292.         account.apiLink = "http://www.livejournal.com/interface/atom";
  293.       }
  294.       return account; 
  295.     }
  296.   }
  297.   return null;
  298. }
  299.  
  300.  
  301. atomWebService.prototype.newPost = function (aListener, aBlogId, aPost, aPublish, aNotifications){
  302.   var gBlogService = Cc['@flock.com/flock-blog;1'].getService(Ci['flockIBlogService']);
  303.   var listener = new atomListener(aListener);
  304.   var atomEntry = {title: aPost.title, content: aPost.description};
  305.   var account = gBlogService.getAccount(aBlogId);
  306.  
  307.   var labels = new Array();
  308.   if (aPost.tags)
  309.     while (aPost.tags.hasMore())
  310.       labels.push(aPost.tags.getNext());
  311.   if (labels.length > 0)
  312.     atomEntry.categories = labels;
  313.   flockAtomPost (listener, account.apiLink, atomEntry,
  314.                  new Array(account.username, account.password));
  315. }
  316.  
  317. atomWebService.prototype.editPost = function (aListener, aBlogAccount, aPostid, aTitle, aDescription, aTags, aDateCreated, aPublish, aEditURI, aAtomID, aNotifications){
  318.   var listener = new atomListener(aListener);
  319.   var atomEntry = { id: aAtomID, title: aTitle, content: aDescription, issued: aDateCreated};
  320.   var labels = new Array();
  321.   while (aTags.hasMore())
  322.     labels.push(aTags.getNext());
  323.   if (labels.length > 0)
  324.     atomEntry.categories = labels;
  325.   flockAtomEdit (listener, aEditURI, atomEntry,
  326.                  new Array(aBlogAccount.username, aBlogAccount.password));
  327. }
  328.  
  329. atomWebService.prototype.deletePost = function (aListener, aBlogAccount, aPostid){
  330.   var url = aBlogAccount.apiLink;
  331.   url += "/" + aPostid;
  332.   // if(aEditURI) url = aEditURI;
  333.   this.doRequest(aListener,"DELETE", url, null, this.handleDelete, aBlogAccount.username, aBlogAccount.password);
  334. }
  335.  
  336. atomWebService.prototype.setPostCategories = function (aListener, aAccount, aPostid, aCategories){
  337.   aListener.onResult(null);
  338. }
  339.  
  340. atomWebService.prototype.getPost = function (aListener, aAccount, aPostid){
  341.   var url = aAccount.apiLink;
  342.   if(aPostid) url += "/" + aPostid;
  343.   var myListener = {
  344.     onResult: function(aResult) {
  345.       var rval = aResult[0];
  346.       aListener.onResult(rval);
  347.     },
  348.     onError: function(aError) {
  349.       aListener.onError(aError);
  350.     },
  351.     onFault: function(aFault) {
  352.       aListener.onFault(aFault);
  353.     },
  354.   };
  355.   this.doRequest(myListener,"GET", url, null, this.parseRecentPosts, aBlogAccount.username, aBlogAccount.password);
  356. }
  357.  
  358. atomWebService.prototype.getUsersBlogs = function (aListener, aAccount){
  359.   //var url = aAccount.apiLink.match(/(.+)\//);
  360.   //url = RegExp.$1;
  361.   url = aAccount.apiLink;
  362.   debug("getUsersBlog... "+url+"\n");
  363.   this.doRequest(aListener,"GET", url, null, this.parseUsersBlogs, aAccount.username, aAccount.password);
  364. }
  365.  
  366. atomWebService.prototype.getRecentPosts = function (aListener, aBlogId, aNumber){
  367.   var blogService = Cc['@flock.com/flock-blog;1'].getService(Ci.flockIBlogService);
  368.   var account = blogService.getAccount(aBlogId);
  369.  
  370.   var url = account.apiLink; 
  371.   //url.match(/(.+\/)(.+)/);
  372.   //if(RegExp.$2=="post") {
  373.   //  url = RegExp.$1 + "feed";
  374.   //}
  375.   debug("getRecentPosts with url = "+url+"\n");
  376.   this.doRequest(aListener, "GET", url, null, this.parseRecentPosts, account.username, account.password);
  377. }
  378.  
  379. atomWebService.prototype.getCategoryList = function (aListener, aAccount){
  380.   aListener.onResult(null);
  381. }
  382.  
  383. atomWebService.prototype.flags = Ci.nsIClassInfo.SINGLETON;
  384. atomWebService.prototype.contractID = FLOCK_ATOM_CONTRACTID;
  385. atomWebService.prototype.classDescription = "Flock ATOM API Service";
  386. atomWebService.prototype.getInterfaces = function (count) {
  387.   var interfaceList = [Ci.flockIWebService,
  388.     Ci.flockICustomBlogWebService,
  389.     Ci.flockIBlogWebService,
  390.       Ci.nsIClassInfo,
  391.       Ci.nsISupports];
  392.   count.value = interfaceList.length;
  393.   return interfaceList;
  394. }
  395. atomWebService.prototype.getHelperForLanguage = function (count) {return null;}
  396.  
  397. // Module implementation
  398. var AtomModule = new Object();
  399.  
  400. AtomModule.registerSelf =
  401. function (compMgr, fileSpec, location, type) {
  402.   compMgr = compMgr.QueryInterface(Ci.nsIComponentRegistrar);
  403.  
  404.   compMgr.registerFactoryLocation(FLOCK_ATOM_CID, 
  405.                   "Flock Blogger JS Component",
  406.                   FLOCK_ATOM_CONTRACTID, 
  407.                   fileSpec, 
  408.                   location,
  409.                   type);
  410.   //necessary category registration
  411.   var catmgr = Cc["@mozilla.org/categorymanager;1"]
  412.     .getService (Ci.nsICategoryManager);
  413.   catmgr.addCategoryEntry('flockICustomBlogWebService', 'atom', FLOCK_ATOM_CONTRACTID, true, true);
  414. }
  415.  
  416. AtomModule.getClassObject =
  417. function (compMgr, cid, iid) {
  418.   if (!cid.equals(FLOCK_ATOM_CID))
  419.     throw Components.results.NS_ERROR_NO_INTERFACE;
  420.   
  421.   if (!iid.equals(Ci.nsIFactory))
  422.     throw Components.results.NS_ERROR_NOT_IMPLEMENTED;
  423.   
  424.   return AtomServiceFactory;
  425. }
  426.  
  427. AtomModule.canUnload =
  428. function(compMgr) {
  429.   return true;
  430. }
  431.   
  432. /* factory object */
  433. var AtomServiceFactory = new Object();
  434.  
  435. AtomServiceFactory.createInstance =
  436. function (outer, iid) {
  437.   if (outer != null)
  438.     throw Components.results.NS_ERROR_NO_AGGREGATION;
  439.  
  440.   return (new atomWebService()).QueryInterface(iid);
  441. }
  442.  
  443. /* entrypoint */
  444. function NSGetModule(compMgr, fileSpec) {
  445.   return AtomModule;
  446. }
  447.